/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.api.commonstructure;

import com.inspur.edp.caf.cef.schema.structure.CommonStructure;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.entity.commonstructure.CefCommonStructureUtil;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.entity.GspCommonModel;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataRTService;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.ArrayList;
import java.util.List;

public class UdtCommonStructureUtil extends CefCommonStructureUtil {

  public static UdtCommonStructureUtil getInstance() {
    return new UdtCommonStructureUtil();
  }

  protected UdtCommonStructureUtil() {
  }

  @Override
  protected CommonStructure getRefBeCommonStructure(GspAssociation asso) {
    MetadataRTService service = SpringBeanUtils.getBean(MetadataRTService.class);
    GspMetadata sourceBeMeta = service.getMetadata(asso.getRefModelID());
    if (sourceBeMeta == null) {
      throw new RuntimeException(getExpressionMessage(asso));
    }
    GspCommonModel sourceBe = (GspCommonModel) sourceBeMeta
        .getContent();
    if (sourceBe == null) {
      throw new RuntimeException(getExpressionMessage(asso));
    }
    GspCommonModel be = sourceBe.clone();
    IGspCommonObject refObj = be.findObjectById(asso.getRefObjectID());
    refObj.setID(getRefObjId(asso));
    IGspCommonObject refObjCopy = refObj.clone(refObj.getParentObject());
    IGspCommonField parentElement = asso.getBelongElement();
    refObj.getContainElements().clear();

    // ID字段
    IGspCommonField idElement = refObjCopy
        .findElement(refObjCopy.getColumnGenerateID().getElementID());
    IGspCommonField newIdElement = idElement
        .clone(idElement.getBelongObject(), idElement.getParentAssociation());
    newIdElement
        .setLabelID(parentElement != null ? parentElement.getLabelID() : newIdElement.getLabelID());
    refObj.getContainElements().add(newIdElement);
    // 关联带出字段
    for (IGspCommonField refEle : asso.getRefElementCollection()) {
      IGspCommonElement targetElement = refObjCopy.findElement(refEle.getRefElementId());
      IGspCommonField newRefElement = targetElement.clone(targetElement.getBelongObject(), targetElement.getParentAssociation());
      newRefElement.setLabelID(getRefElementLabelId(targetElement.getLabelID(), parentElement));
      refObj.getContainElements().add(newRefElement);
    }
    return be;
  }

  private String getRefElementLabelId(String currentLabelId, IGspCommonField belongElement) {

    String labelIdPrefix = belongElement != null ? belongElement.getLabelID()+"_" : "";
    return labelIdPrefix+currentLabelId;
  }

  @Override
  protected CommonStructure getRefUdtCommonStructure(String udtId) {
    MetadataRTService service = SpringBeanUtils.getBean(MetadataRTService.class);
    GspMetadata udtMeta = service.getMetadata(udtId);
    if (udtMeta == null) {
      throw new RuntimeException("加载引用的UDT元数据失败，udtId=" + udtId);
    }
    UnifiedDataTypeDef udt = (UnifiedDataTypeDef) udtMeta.getContent();
    return udt;
  }

  public List<CommonStructure> getElementsRefStructures(List<IGspCommonField> fields) {
    List<CommonStructure> list = new ArrayList<CommonStructure>();
    for (IGspCommonField field : fields) {
      if (field.getIsUdt()) {
        list.add(getRefUdtCommonStructure(field.getUdtID()));
        continue;
      }
      if (field.getObjectType() == GspElementObjectType.Association) {
        for (GspAssociation asso : field.getChildAssociations()) {
          list.add(getRefBeCommonStructure(asso));
        }
        continue;
      }
    }
    return list;
  }
  private String getExpressionMessage(GspAssociation asso){
    StringBuilder strBuilder = new StringBuilder("加载引用BE元数据失败,元数据包名:【");
    strBuilder.append(asso.getRefModelPkgName())
        .append("】,BE名称:【")
        .append(asso.getRefModelName())
        .append("】,BE ID:【")
        .append(asso.getRefModelID())
        .append("】");
    return strBuilder.toString();
  }
}
